﻿using System;
using System.Collections.Generic;
using MicroContainer;

namespace MicroContainer.CompileTime
{
   /// <summary>
   /// Records the type mappings defined in container creation method and validates their formal correctnes.
   /// An instance should be used only ones as an argument to container creation method and then discarded.
   /// </summary>
   internal class ContainerBuilder : IContainerBuilder
   {
      private readonly Dictionary<TypeMappingKey, TypeMappingDef> _mappingDefinitions = new Dictionary<TypeMappingKey, TypeMappingDef>();

      #region Interface
      /// <summary>
      /// Returns all the recorded mappings. 
      /// </summary>
      /// <returns></returns>
      internal IDictionary<TypeMappingKey, TypeMappingDef> GetMappings()
      {
         return _mappingDefinitions;
      }
      #endregion

      #region IContainerBuilder Members 
      public IMicroContainer Build()
      {
         return null;
      }
      public IContainerBuilder RegisterType(Type from, Type to)
      {
         return RegisterType(from, to, null);
      }
      public IContainerBuilder RegisterType(Type from, Type to, string name)
      {
         return RegisterType(from, to, name, InstantiationMode.Transient);
      }
      public IContainerBuilder RegisterType(Type from, Type to, string name, InstantiationMode mode)
      {
         TypeMappingKey key = new TypeMappingKey(from, name);
         if (_mappingDefinitions.ContainsKey(key))
         {
            throw new FatalErrorException("MC001", key);
         }
         _mappingDefinitions[key] =new TypeMappingDef(from, to, name, mode);
         return this;
      }
      public IContainerBuilder RegisterType(Type from, Delegate to, string name, InstantiationMode mode)
      {
         TypeMappingKey key = new TypeMappingKey(from, name);
         if (_mappingDefinitions.ContainsKey(key))
         {
            throw new FatalErrorException("MC001", key);
         }
         _mappingDefinitions[key] = new TypeMappingDef(from, to, name, mode);
         return this;
      }
      public IContainerBuilder RegisterType(Type from, Delegate to, string name)
      {
         return RegisterType(from, to, name, InstantiationMode.Transient);
      }
      public IContainerBuilder RegisterType(Type from, Delegate to)
      {
         return RegisterType(from, to, null);
      }
      #endregion
   }
}
